/* $Id: SubmissionsModel.java 129 2011-08-26 05:27:43Z altdotua@gmail.com $ */

package alt.djudge.frontend.server.models;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import org.hibernate.criterion.Order;

import alt.djudge.frontend.server.Deployment;
import alt.djudge.frontend.server.datatypes.SubmissionDetailsEntry;
import alt.djudge.frontend.server.datatypes.SubmissionEntry;
import alt.djudge.frontend.server.datatypes.SubmissionFull;


public class SubmissionsModel
{
	private static CoreInterface<SubmissionEntry> core = Deployment.isGAE() ? 
		new AbstractBigtableModelCore<SubmissionEntry>()
		{
			@Override
			protected Order getOrdering()
			{
				return Order.desc("submissionTime");
			}
			
			@Override
			protected Class<SubmissionEntry> getEntryClass()
			{
				return SubmissionEntry.class;
			}
			
			protected Integer getPageSize()
			{
				return 20;
			}
		}
	:
		new AbstractDBModelCore<SubmissionEntry>()
		{
			@Override
			protected Order getOrdering()
			{
				return Order.desc("submissionTime");
			}
			
			@Override
			protected Class<SubmissionEntry> getEntryClass()
			{
				return SubmissionEntry.class;
			}
		};
		
		private static CoreInterface<SubmissionDetailsEntry> detailsCore = Deployment.isGAE() ? 
				new AbstractBigtableModelCore<SubmissionDetailsEntry>()
				{
					@Override
					protected Order getOrdering()
					{
						return Order.desc("id");
					}
					
					@Override
					protected Class<SubmissionDetailsEntry> getEntryClass()
					{
						return SubmissionDetailsEntry.class;
					}
				}
			:
				new AbstractDBModelCore<SubmissionDetailsEntry>()
				{
					@Override
					protected Order getOrdering()
					{
						return Order.desc("id");
					}
					
					@Override
					protected Class<SubmissionDetailsEntry> getEntryClass()
					{
						return SubmissionDetailsEntry.class;
					}
				};
				
/*	public static String insertNew(Long userId, Long problemId, Long languageId, String sourceCode, Boolean fFirstTestOnly, String ip)
	{
		ContestProblemEntry contestProblemEntry = ContestProblemsModel.getEntry(problemId.toString());
		ContestEntry contestEntry = ContestsModel.getEntry(contestProblemEntry.getContestId().toString());
		
		UserEntry user = UsersModel.getUser(userId);
		
		// FIXME
		if (!user.isAdmin())
			if (contestEntry.getStartTime().after(new Date()) || contestEntry.getFinishTime().before(new Date()))
				return "0";

		SubmissionDetailsEntry submissionDetails = new SubmissionDetailsEntry();
		submissionDetails.setSourceCode(new String(sourceCode));
		submissionDetails.makePersistent();
		
		SubmissionEntry submission = new SubmissionEntry();
		
		submission.setSubmissionDetailsId(submissionDetails.getId());
		submission.setLanguageId(languageId);
		submission.setContestProblemId(problemId);
		submission.setContestId(ContestProblemsModel.getEntry(problemId.toString()).getContestId());
		submission.setUserId(userId);
		submission.setFlagFirstTestOnly(fFirstTestOnly);
		submission.setSourceSize(sourceCode.length());
		submission.setIpAddress(ip);
		// FIXME: virtual contests
		submission.setContestTime((new Date().getTime() - contestEntry.getStartTime().getTime()) / 1000);

		if (!fFirstTestOnly)
		{
			submission.incrementPendingsCount();
		}		
		
		submission.makePersistent();
		
		return submission.getId().toString();
	}
*/
	
	
	public static SubmissionFull getDJudgeTask()
	{
		HashMap<String, Object> map = new HashMap<String, Object>();
		//map.put("active", true);
		map.put("djudgeFlag", 0);
		List<SubmissionEntry> list = core.getEntries(map);
		if (list.size() == 0)
			return null;
		return SubmissionsModel.getSubmissionFull(list.get(list.size()-1).getId());
	}

	public static SubmissionEntry getSubmission(Long submissionId)
	{
		return core.getEntry(submissionId);
	}

	public static SubmissionDetailsEntry getSubmissionDetails1(Long submissionId)
	{
		return detailsCore.getEntry(submissionId);
	}

	public static SubmissionDetailsEntry getSubmissionDetails(Long submissionDetailsId)
	{
		return detailsCore.getEntry(submissionDetailsId);
	}
	
	public static SubmissionFull getSubmissionFull(Long submissionId)
	{
		SubmissionFull res = new SubmissionFull();
		res.setSubmissionEntry(getSubmission(submissionId));
		res.setSubmissionDetailsEntry(getSubmissionDetails(res.getSubmissionEntry().getSubmissionDetailsId()));
		return res.getSubmissionDetailsEntry() != null && res.getSubmissionEntry() != null ? res : null;
	}

	public static List<SubmissionEntry> getSubmissions(Long userId)
	{
		try
		{
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("userId", userId);
			return core.getEntries(map);
		}
		catch (Exception e)
		{
			return new Vector<SubmissionEntry>();
		}
	}
	
	public static List<SubmissionEntry> getSubmissions(Map<String, Object> req)
	{
		return core.getEntries(req);
	}
	
	public static List<SubmissionEntry> getAllSubmissions()
	{
		return core.getAllEntries();
	}
	
	
	public static boolean disableSubmission(Long submissionId)
	{
		SubmissionEntry entry = getSubmission(submissionId);
		if (null == entry)
			return false;
		entry.setActive(!entry.getActive());
		return entry.makePersistent();
	}
	
	public static boolean deleteSubmission(Long submissionId)
	{
		SubmissionEntry entry = getSubmission(submissionId);
		if (null == entry)
			return false;
		return entry.delete();
	}

	
	public static CoreInterface<SubmissionEntry> getCore()
	{
		return core.getAdapter();
	}
	
	/*
	public static HashMap<Long, SubmissionEntry> getUserProblemStatus2(String contestId, Long userId)
	{
		HashMap<Long, SubmissionEntry> res = new HashMap<Long, SubmissionEntry>();
		try
		{
			List<ContestProblemEntry> listPr = ContestProblemsModel.getContestEntries(contestId);
			for (ContestProblemEntry pe: listPr)
			{
				HashMap<String, Object> filter = new HashMap<String, Object>();
				filter.put("userId", userId);
				filter.put("contestProblemId", pe.getId());
				filter.put("active", true);
				filter.put("flagFirstTestOnly", false);
				List<SubmissionEntry> listSubm = getSubmissions(filter);
				int maxScore = -1;
				//boolean f = false;
				SubmissionEntry bestSubm = null;
				Collections.reverse(listSubm);
				for (SubmissionEntry se: listSubm)
					if (se.getScore() > maxScore)
					{
						maxScore = se.getScore();
						bestSubm = se;
						break;
					}
				res.put(pe.getId(), bestSubm);
			}
		}
		catch (Exception e) {}
		return res;
	}*/
	
	/*
	public static HashMap<Long, ProblemUserScoreEntry> getUserProblemStatus(String contestId, Long userId)
	{
		String key = CacheModel.getCPUSMapByContestUserKey(contestId, userId);
		Cache cache = CacheModel.getStaticCache();
		HashMap<Long, ProblemUserScoreEntry> res = (HashMap<Long, ProblemUserScoreEntry>) cache.get(key);
		if (res == null)
		{	
			res = new HashMap<Long, ProblemUserScoreEntry>();
			try
			{
				List<ContestProblemEntry> listPr = ContestProblemsModel.getContestEntries(contestId);
				for (ContestProblemEntry pe: listPr)
				{
					ProblemUserScoreEntry entry = ProblemUserScoreModel.getProblemUserEntry(pe.getId(), userId);
					res.put(pe.getId(), entry);
				}
			}
			catch (Exception e) {}
		}
		return res;
	}*/
}
